package trading.algo.BearToBullTask;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import trading.algo.STKBuyOrderTask;
import trading.algo.STKShortSellingTask;
import trading.algo.TimerKillerTask;
import trading.algo.UpdateAccountValueTask;
import trading.algo.BearTask.SyncOptionPositionAndOrderTask;
import trading.bo.DBAccessorBO;
import trading.bo.EmailAccessorBO;
import trading.bo.IBAccessorBO;
import trading.dataentry.OptionPositionOrOrder;
import trading.dataentry.StockPositionOrOrder;
import trading.util.OrderSplitHelper;

public class CleanPositionTask extends TimerTask {

    private DBAccessorBO dbAccessorBO;
    private IBAccessorBO ibAccessorBO;
    private EmailAccessorBO emailAccessorBO;
    private OrderSplitHelper orderSplitHelper;

    public CleanPositionTask(IBAccessorBO ibAccessorBO,
            DBAccessorBO dbAccessorBO, EmailAccessorBO emailAccessorBO, OrderSplitHelper orderSplitHelper) {
        this.ibAccessorBO = ibAccessorBO;
        this.dbAccessorBO = dbAccessorBO;
        this.emailAccessorBO = emailAccessorBO;
        this.orderSplitHelper = orderSplitHelper;
    }

    @Override
    public void run() {
        // Step 1: check portfolio option positions
        List<OptionPositionOrOrder> optionPositions = this.dbAccessorBO
                .getPortfolioOptionPositions();

        // Step 2: create stub open option order list
        List<OptionPositionOrOrder> optionOrders = new ArrayList<OptionPositionOrOrder>();

        // Step 3: create mkt order to clean up portfolio option positions
        SyncOptionPositionAndOrderTask syncTask = new SyncOptionPositionAndOrderTask(
                optionOrders, optionPositions, ibAccessorBO, emailAccessorBO);
        Timer timer = new Timer();
        int taskId = 0;
        timer.schedule(syncTask, taskId * 1000);
        taskId += 2;

        // Step 4: check portfolio stock positions
        List<StockPositionOrOrder> stockPositions = this.dbAccessorBO
                .getPortfolioStockPositions();

        // Step 5: create orders to clean the stock positions
        for (int i = 0; i < stockPositions.size(); i++, taskId += 2) {
            StockPositionOrOrder position = stockPositions.get(i);
            int size = Integer.parseInt(position.getQuantity());
            if (size < 0) {
                STKBuyOrderTask task = new STKBuyOrderTask(size * -1,
                        position.getTicker(), this.ibAccessorBO, emailAccessorBO, orderSplitHelper, true);
                timer.schedule(task, taskId * 1000);
            } else {
                STKShortSellingTask task = new STKShortSellingTask(
                        position.getTicker(), size, this.ibAccessorBO, emailAccessorBO, orderSplitHelper, true);
                timer.schedule(task, taskId * 1000);
            }
        }

        taskId += 600;

        // Step 9: update portfolio positions
        timer.schedule(new UpdateAccountValueTask(ibAccessorBO, dbAccessorBO, true),
                taskId * 1000);
        taskId += 5;

        TimerKillerTask timerKillerTask = new TimerKillerTask(timer);
        timer.schedule(timerKillerTask, taskId * 1000);
    }

}
